package main

import (
	"github.com/gin-gonic/gin"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

func RegisterRouter() *gin.Engine {
	r := gin.Default()
	r.Use(RateLimiterMiddleware())
	r.GET("/videos/:vid-id", streamHandler)
	r.POST("/upload/:vid-id", uploadHandler)
	r.GET("/upload", UploadPage)
	return r
}
func streamHandler(c *gin.Context) {
	vid := c.Param("vid-id")
	vl := VIDEO_DIR + vid + VIDEO_SUFFIX
	log.Printf("video linke:%s", vl)
	video, err := os.Open(vl)
	if err != nil {
		log.Println(err)
		sendErrorResponsr(c, http.StatusInternalServerError, "Open file Internal error")
		return
	}
	c.Header("Content-Type", "video/mp4")                         //告知浏览器 把比特流解析为视频
	http.ServeContent(c.Writer, c.Request, "", time.Now(), video) //传入视频，第三个参数来保证可以自由拉进度条
	defer video.Close()
}
func uploadHandler(c *gin.Context) {
	//MaxBytesReader防止客户端意外或恶意地发送大请求，浪费服务器资源
	c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, MAX_UPLOAD_SIZE)

	// ParseMultipartForm将请求正文解析为多部分/表单数据。整个请求体被解析，最大总内存字节数为
	//它的文件部分存储在内存中，其余部分存储在 临时文件中的磁盘。
	if err := c.Request.ParseMultipartForm(MAX_UPLOAD_SIZE); err != nil { //提交表单的时候，如果文件大小超过设置好的50MB就会出错
		sendErrorResponsr(c, http.StatusBadRequest, "File is too big")
		return
	}
	//返回表单名字为 表单中 第一个name为 file的内容
	file, _, err := c.Request.FormFile("file") // <form name="file"
	if err != nil {
		sendErrorResponsr(c, http.StatusInternalServerError, "Form file Internal server error")
		return
	}
	data, err := ioutil.ReadAll(file)
	if err != nil {
		sendErrorResponsr(c, http.StatusInternalServerError, "Read file internal error")
		return
	}
	//写入文件 0666
	fn := c.Param("vid-id")
	err = ioutil.WriteFile(VIDEO_DIR+fn+VIDEO_SUFFIX, data, 0666)
	if err != nil {
		sendErrorResponsr(c, http.StatusInternalServerError, "wirte file internal error")
		return
	}
	c.IndentedJSON(200, "upload successfully")
}
func UploadPage(c *gin.Context) {
	files, err := template.ParseFiles("./template/upload.html") //这里的./应该是当前pro的根目录
	if err != nil {
		log.Println(err)
		sendErrorResponsr(c, http.StatusInternalServerError, "Parse file error")
		return
	}
	files.Execute(c.Writer, nil)
}
